import { refresh } from '@/services/user/login';

/**
 * 认证服务：处理Token存储、刷新和过期管理
 */
class AuthService {
  // Token存储键名
  private readonly ACCESS_TOKEN_KEY = 'access_token';
  private readonly REFRESH_TOKEN_KEY = 'refresh_token';
  private readonly EXPIRES_AT_KEY = 'expires_at'; // 过期时间戳(ms)

  // 刷新中的状态锁，防止并发请求重复刷新
  private isRefreshing = false;
  // 等待刷新的请求队列
  private refreshCallbacks: Array<(token: string) => void> = [];

  /**
   * 获取当前的Access Token
   */
  getAccessToken(): string | null {
    return localStorage.getItem(this.ACCESS_TOKEN_KEY);
  }

  /**
   * 获取Refresh Token
   */
  getRefreshToken(): string | null {
    return localStorage.getItem(this.REFRESH_TOKEN_KEY);
  }

  /**
   * 保存Token信息
   * @param accessToken 新的Access Token
   * @param refreshToken 新的Refresh Token
   * @param expiresIn 有效期(秒)
   */
  saveTokens(
    accessToken: string,
    refreshToken: string,
    expiresIn: number,
  ): void {
    const expiresAt = Date.now() + expiresIn * 1000;
    localStorage.setItem(this.ACCESS_TOKEN_KEY, accessToken);
    localStorage.setItem(this.REFRESH_TOKEN_KEY, refreshToken);
    localStorage.setItem(this.EXPIRES_AT_KEY, expiresAt.toString());
  }

  /**
   * 清除所有Token信息
   */
  clearTokens(): void {
    localStorage.removeItem(this.ACCESS_TOKEN_KEY);
    localStorage.removeItem(this.REFRESH_TOKEN_KEY);
    localStorage.removeItem(this.EXPIRES_AT_KEY);
  }

  /**
   * 检查Access Token是否即将过期
   * @param threshold 提前刷新的阈值(秒)，默认60秒
   */
  isTokenExpiringSoon(threshold = 60): boolean {
    const expiresAt = localStorage.getItem(this.EXPIRES_AT_KEY);
    if (!expiresAt) return true;

    const expiresTimestamp = Number(expiresAt);
    const now = Date.now();
    // 检查是否在阈值时间内即将过期
    return expiresTimestamp - now < threshold * 1000;
  }

  /**
   * 主动刷新Token
   */
  async refreshToken(): Promise<string> {
    // 如果正在刷新，加入等待队列
    if (this.isRefreshing) {
      return new Promise((resolve) => {
        this.refreshCallbacks.push(resolve);
      });
    }

    const refreshToken = this.getRefreshToken();
    if (!refreshToken) {
      this.clearTokens();
      throw new Error('No refresh token available');
    }

    try {
      this.isRefreshing = true;

      // 调用刷新Token的API
      const data = await refresh(refreshToken);

      this.saveTokens(data.accessToken, data.refreshToken, data.expireTime);

      // 通知所有等待的请求
      this.refreshCallbacks.forEach((cb) => cb(data.accessToken));
      this.refreshCallbacks = [];

      return data.accessToken;
    } catch (error) {
      // 刷新失败，清除所有Token
      this.clearTokens();
      this.refreshCallbacks = [];
      // 跳转到登录页
      window.location.href = '/login';
      throw error;
    } finally {
      this.isRefreshing = false;
    }
  }

  /**
   * 检查并主动刷新Token（如果即将过期）
   */
  async checkAndRefreshToken(): Promise<string | null> {
    const accessToken = this.getAccessToken();
    if (!accessToken) return null;

    // 如果Token即将过期，主动刷新
    if (this.isTokenExpiringSoon()) {
      return this.refreshToken();
    }

    return accessToken;
  }
}

export const authService = new AuthService();
